///////////////////////////////////////////////////////////////////////////////
// signal handlers                                                           //
///////////////////////////////////////////////////////////////////////////////


// Gtk2.0
#include "gtk/gtk.h"
#include "gdk-pixbuf/gdk-pixbuf.h"
#include <glib.h>

#include "opencv/cv.hpp"
#include "opencv/cxcore.hpp"
#include "glade/glade.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include "vicon.h"

static const char* cascade_name = "/home/dexter/opencv_test/trunk.mv/opencv/data/haarcascades/haarcascade_frontalface_alt.xml";

G_MODULE_EXPORT gboolean on_pixMapArea_expose_event(GtkWidget *widget, GdkEventExpose *event,gpointer data)
{
    GdkWindow     *window;
//    CvImageWidget *cvImgWidget;

    window = widget->window;


    IplImage *frameImage = cvQueryFrame(cam_capture);

    detect_and_draw2(frameImage);

    cvCvtColor(frameImage, frameImage, CV_BGR2RGB);
    /* */

    //gtk_widget_queue_draw(GTK_WIDGET(widget));

    /*
    GdkPixbuf* pixBuff = gdk_pixbuf_new_from_data(( guchar* )frameImage->imageData,
                                             GDK_COLORSPACE_RGB,
                                             FALSE,
                                             frameImage->depth,
                                             frameImage->width,
                                             frameImage->height,
                                             (frameImage->widthStep),
                                             NULL, NULL);



    gdk_draw_pixbuf(widget->window,
                    widget->style->fg_gc[ GTK_WIDGET_STATE( widget )],
                    pixBuff,
                    0, 0, 0, 0,
                    frameImage->width,
                    frameImage->height,
                    GDK_RGB_DITHER_MAX,
                    0, 0);

    g_object_unref(pixBuff);
    */


    gdk_draw_rgb_image( widget->window, widget->style->fg_gc[GTK_STATE_NORMAL],
	                  0, 0, widget->allocation.width, widget->allocation.height,
	                  GDK_RGB_DITHER_MAX, (const guchar*)frameImage->imageData, frameImage->widthStep );


//    gdk_pixbuf_unref(pixBuff);
    gtk_widget_queue_draw(GTK_WIDGET(widget));
    return TRUE;

    GdkGC *black_gc = widget->style->black_gc;
    GdkGC *white_gc = widget->style->white_gc;
    //gdk_draw_arc(window, white_gc, TRUE, 0,0, 50,50, 64*0,64*360);
    gdk_draw_rectangle(widget->window, black_gc, TRUE,0,0, widget->allocation.width, widget->allocation.height);

    GError *error = NULL;
    GdkPixbuf *pix = gdk_pixbuf_new_from_file ("/home/dexter/freeimage.png", &error);
    if (pix == NULL)
    {
        //g_printerr ("Error loading file: #%d %s\n", error->code, error->message);
        printf("Error loading file: #%d %s\n", error->code, error->message);
        g_error_free (error);
        gdk_draw_arc(window, white_gc, TRUE, 0,0, 50,50, 64*0,64*360);
        return FALSE;
    }
    gdk_draw_pixbuf( widget->window,
                    widget->style->fg_gc[ GTK_WIDGET_STATE( widget )],
                    pix,
                    0, 0, ((widget->allocation.width)/2) - (256/2), ((widget->allocation.height)/2) - (256/2),
                    256,
                    256,
                    GDK_RGB_DITHER_MAX,
                    0, 0);

    gdk_pixbuf_unref(pix);
  return TRUE;
}

// Function to detect and draw any faces that is present in an image
G_MODULE_EXPORT void detect_and_draw2( IplImage* img )
{
    // Create memory for calculations
    static CvMemStorage* storage = 0;
    // Create a new Haar classifier
    static CvHaarClassifierCascade* cascade = 0;


    int scale = 1;

    // Create a new image based on the input image
    IplImage* temp = cvCreateImage( cvSize(img->width/scale,img->height/scale), 8, 3 );

    // Create two points to represent the face locations
    CvPoint pt1, pt2;
    int i;

    // Load the HaarClassifierCascade
    if(!cascade)
    {
        cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
    }

    // Check whether the cascade has loaded successfully. Else report and error and quit
    if( !cascade )
    {
        fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
        return;
    }

    // Allocate the memory storage
    storage = cvCreateMemStorage(0);

    // Create a new named window with title: result
    //cvNamedWindow( "result", 1 );

    // Clear the memory storage which was used before
    cvClearMemStorage( storage );
    // Find whether the cascade is loaded, to find the faces. If yes, then:
    if( cascade )
    {

        // There can be more than one face in an image. So create a growable sequence of faces.
        // Detect the objects and store them in the sequence
        //1.1, 2, CV_HAAR_DO_CANNY_PRUNING,
        /*
        CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,
                                           		1.1,                       // increase search scale by 10% each pass
                                                3,                         // merge groups of three detections
                                                CV_HAAR_DO_CANNY_PRUNING,
                                            cvSize(40, 40), cvSize(0,0));

        // Loop the number of faces found.
        for( i = 0; i < (faces ? faces->total : 0); i++ )
        {
           // Create a new rectangle for drawing the face
            CvRect* r = (CvRect*)cvGetSeqElem( faces, i );

            // Find the dimensions of the face,and scale it if necessary
            pt1.x = r->x*scale;
            pt2.x = (r->x+r->width)*scale;
            pt1.y = r->y*scale;
            pt2.y = (r->y+r->height)*scale;

            // Draw the rectangle in the input image
            cvRectangle( img, pt1, pt2, CV_RGB(0,128,0), 1, CV_AA, 0 );


            CvScalar color = CV_RGB(0,255,0);
            pt1 = cvPoint(0, (r->y+(r->height/2))*scale);
            pt2 = cvPoint(img->width, (r->y+(r->height/2))*scale);

            cvLine(img, pt1, pt2, CV_RGB(0,255,0),1, CV_AA, 0 );

            pt1 = cvPoint((r->x+(r->width/2))*scale, 0);
            pt2 = cvPoint((r->x+(r->width/2))*scale, img->height);
            cvLine(img, pt1, pt2, CV_RGB(0,255,0),1, CV_AA, 0 );
        }
        */
    }

    // Release the temp image created.
    cvReleaseImage( &temp );
}

G_MODULE_EXPORT CvCapture* open_cam(int index)
{
    cam_capture = cvCaptureFromCAM( CV_CAP_ANY ); //CV_CAP_ANY
    //capture = cvCreateCameraCapture(0);
    if(!cam_capture) { printf("Capture did not work\n");return NULL;}
    else { printf("capture device ok\n");}

    cvSetCaptureProperty(cam_capture, CV_CAP_PROP_FRAME_WIDTH, 160 ); //640
    cvSetCaptureProperty(cam_capture, CV_CAP_PROP_FRAME_HEIGHT, 120 ); //360


    return cam_capture;
}

G_MODULE_EXPORT void close_cam( CvCapture** cam_capture )
{
    return;
}



